package com.zhdl.hardware_contact.hardware_common.repository.impl;

import com.zhdl.common.ytools.BaseConversionTools;
import com.zhdl.common.ytools.callback.CommonCallback;
import com.zhdl.hardware_contact.hardware_common.param.CurrencyProtocolReadReq;
import com.zhdl.hardware_contact.hardware_common.param.CurrencyProtocolWriteReq;
import com.zhdl.hardware_contact.hardware_common.param.RtuAssembleCmdPkg;
import com.zhdl.hardware_contact.hardware_common.repository.CurrencyProtocolCmdHandleService;
import com.zhdl.network.common_client.CommonSerialClientAfter;
import com.zhdl.network.common_client.CommonSerialClientAnalysis;
import com.zhdl.network.strategy.common_client.CommonProtocolService;
import com.zhdl.network.strategy.common_client.dto.SendReceiverData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;


@Slf4j
@Service("RTUProtocolCmdHandleServiceImpl")
public class RTUProtocolCmdHandleServiceImpl implements CurrencyProtocolCmdHandleService {

    @Resource
    private CommonProtocolService commonProtocolService;

    /**
     * 添加网口 IP+端口
     * 配置协议 为Null 则默认一条协议 RTU/TCP
     * 配置后置 为Null 则默认一条后置 RTU/TCP
     *
     * @param sendReceiverData IP Protocol After
     */
    @Override
    public void addIpPort(SendReceiverData sendReceiverData) {
        if (sendReceiverData.getProtocols() == null || sendReceiverData.getProtocols().isEmpty()) {
            sendReceiverData.setProtocols(CommonSerialClientAnalysis.MODBUS_ANALYSIS);
        }
        if (sendReceiverData.getAfter() == null || sendReceiverData.getAfter().isEmpty()) {
            sendReceiverData.setAfter(CommonSerialClientAfter.MODBUS_RTU_AFTER_SERVICE);
        }
        if (sendReceiverData.getPort() == null || sendReceiverData.getPort().isEmpty()) {
            log.error("TCPProtocolCmdHandleServiceImpl 未找到IP地址的配置");
        } else {
            commonProtocolService.initPort(sendReceiverData);
        }
    }

    /**
     * 通用协议-读取功能码01 读线圈
     *
     * @param protocolReadReq 读取参数
     * @param callback        回调
     */
    @Override
    public void readFunctionCode01(String port, CurrencyProtocolReadReq protocolReadReq, CommonCallback<String> callback) {
        try {
            byte[] bytes = RtuAssembleCmdPkg.read01(protocolReadReq);
            commonProtocolService.sendCmd(port,
                    BaseConversionTools.byteArrayToHex(bytes), s -> {
                        log.debug("readFunctionCode01-->callback:{}", s);
                        callback.statusCallback(s);
                    });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通用协议-读取功能码03 读保持寄存器
     *
     * @param protocolReadReq 读取参数
     * @param callback        回调
     */
    @Override
    public void readFunctionCode03(String port, CurrencyProtocolReadReq protocolReadReq, CommonCallback<String> callback) {
        try {
            byte[] bytes = RtuAssembleCmdPkg.read03(protocolReadReq);
            commonProtocolService.sendCmd(port,
                    BaseConversionTools.byteArrayToHex(bytes), s -> {
                        log.debug("readFunctionCode03-->callback:{}", s);
                        callback.statusCallback(s);
                    });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通用协议-写入功能码05 写入单个线圈
     *
     * @param protocolWriteReq 写入参数
     */
    @Override
    public void writeFunctionCode05(String port, CurrencyProtocolWriteReq protocolWriteReq) {
        try {
            byte[] bytes = RtuAssembleCmdPkg.write05(protocolWriteReq);
            commonProtocolService.sendCmd(port,
                    BaseConversionTools.byteArrayToHex(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通用协议-写入功能码15 写入多个线圈
     *
     * @param port
     * @param protocolWriteReq 写入参数
     */
    @Override
    public void writeFunctionCode15(String port, CurrencyProtocolWriteReq protocolWriteReq) {
        log.info("暂无");
    }

    /**
     * 通用协议-写入功能码06 写入单个寄存器
     *
     * @param protocolWriteReq 写入参数
     */
    @Override
    public void writeFunctionCode06(String port, CurrencyProtocolWriteReq protocolWriteReq) {
        try {
            byte[] bytes = RtuAssembleCmdPkg.write06(protocolWriteReq);
            commonProtocolService.sendCmd(port,
                    BaseConversionTools.byteArrayToHex(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通用协议-写入功能码10 写入多个寄存器
     * 注: RTU则功能码为16
     *
     * @param protocolWriteReq 写入参数
     */
    @Override
    public void writeFunctionCode10(String port, CurrencyProtocolWriteReq protocolWriteReq) {
        try {
            byte[] bytes = RtuAssembleCmdPkg.write10(protocolWriteReq);
            commonProtocolService.sendCmd(port,
                    BaseConversionTools.byteArrayToHex(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 自定义协议-测试
     */
    @Override
    public void customFunctionCodeDemo() {

    }

}
